iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0

Takeaway

  • 嵌套裡的物件用展開語法會寫成像這樣:...person.artwork
  • 被嵌套的物件看似像被嵌套,但其實狀態上有點像淺拷貝
  • 讓嵌套裡的物件可以更直觀被取得的方式:使用Immer
  • 先import並const useImmer(不是useState了),再到Immer版的setter(以update開頭)裡用draft取代state變數寫箭頭函式。draft相當於Proxy
  • 不直接改state導致mutation的好處:好除錯、有助優化、有助版控或reset(需求變更時更彈性)
  • 因為+=是mutation,所以即便計算結果相同,在setter物件裡仍要修正成+
  • 因為draft能作為Proxy,所以在Immer裡是可以寫+=的!
  • Immer讓React不只是immutable
  • 不要用會改變原始陣列的方法,像slice可以用,splice不能。或者引入Immer就都可以寫了
  • 把展開語法寫在後面,就可以實作插入前面的unshift
  • 複製陣列之後就可以用sort和reverse了
  • 增:setter搭配展開語法;刪:setter搭配filter;改:setter搭配map

先來看以下這段程式碼:

setPlayer({
  ...player,
  score: player.score + 1
});

要寫這麼費工的原因是,我們不能直接改player.score。
score: player.score + 1,代表和前面State裡變得不同的鍵值對。
…player則可以代表,需要和前面State裡保持一致的鍵值對。


Edit State3

另一個練習我們寫購物車的遞減按鈕,但從1減到0時要直接把項目移除。
首先自然是把遞增按鈕的程式碼複製過來,把綁定的事件處理函數改成handleDecreaseClick,邏輯只差在變成減一。

然後我的做法是直接在onClick這,用if判斷+filter濾出要保留的項目,再麻煩setProducts送出。
一開始條件設成p => p.count > 1,很開心想說寫完了。但此時萬一有兩個項目剛好都剩1的話,會一起被送走。所以要改成p => p.id != product.id,也就是保留「不符合if條件的id」所代表的項目,才能正確破關。

<button
onClick={() => {
  handleDecreaseClick(product.id);
  if (product.count < 2) {
    setProducts(products.filter((p) => p.id != product.id));
  }
}}
>
-
</button>

上一篇
【Day8】State2
下一篇
【Day10】State managing 1
系列文
【現在學React還來得及嗎?】30天Takeaway分享30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言